/*******************************************************************************
 * Copyright (c) 2025-08-08 @author <a href="mailto:iffiff1@gmail.com">Tyler Chen</a>.
 * All rights reserved.
 *
 * Contributors:
 *     <a href="mailto:iffiff1@gmail.com">Tyler Chen</a> - initial API and implementation.
 ******************************************************************************/
package org.iff.util.llm.glm;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * TextChat
 * <pre>
 * {
 *     "id":"id"
 *     "request_id": "request_id",
 *     "created:1688737600,
 *     "model":"glm-4",
 *     "choices": [
 *         {
 *             "index": 1,
 *             "finish_reason": "finish_reason",
 *             "message": {
 *                 "role": "assistant",
 *                 "content": [
 *                     {
 *                         "type": "type",
 *                         "text": "text"
 *                     }
 *                 ],
 *                 "reasoning_content": "test",
 *                 "audio": {
 *                     "id": "id",
 *                     "data": "base64",
 *                     "expires_at": "time",
 *                     "tool_calls": [
 *                         {
 *                             "id": "id",
 *                             "type": "type",
 *                             "function": {
 *                                 "name": "name",
 *                                 "arguments": {}
 *                             },
 *                             "mcp": {
 *                                 "id": "id",
 *                                 "type": "type",
 *                                 "server_label": "server_label",
 *                                 "error": "error",
 *                                 "tools": [
 *                                     {
 *                                         "name": "name",
 *                                         "description": "description",
 *                                         "annotations": {},
 *                                         "input_schema": {
 *                                             "type": "type",
 *                                             "properties": {},
 *                                             "required": [
 *                                                 "s1",
 *                                                 "s2"
 *                                             ],
 *                                             "additionalProperties": true
 *                                         }
 *                                     }
 *                                 ],
 *                                 "arguments": "arguments",
 *                                 "name": "name",
 *                                 "output": {}
 *                             }
 *                         }
 *                     ]
 *                 }
 *             }
 *         }
 *     ],
 *     "usage": {
 *         "prompt_tokens": 1,
 *         "completion_tokens": 1,
 *         "prompt_tokens_details": {
 *             "cached_tokens": 1
 *         }
 *     },
 *     "video_result": [
 *         {
 *             "url": "url",
 *             "cover_image_url": "url"
 *         }
 *     ],
 *     "web_search": [
 *         {
 *             "icon": "icon",
 *             "title": "title",
 *             "link": "link",
 *             "media": "media",
 *             "publish_date": "publish_date",
 *             "content": "content",
 *             "refer": "refer"
 *         }
 *     ],
 *     "content_filter": [
 *         {
 *             "role": "role",
 *             "level": 0
 *         }
 *     ]
 * }
 * </pre>
 *
 * @author <a href="mailto:iffiff1@gmail.com">Tyler Chen</a>
 * @since 2025-08-08
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TextChat {
    @JsonProperty("id")
    private String id;
    @JsonProperty("request_id")
    private String requestId;
    @JsonProperty("created")
    private Integer created;
    @JsonProperty("model")
    private String model;
    @JsonProperty("choices")
    private List<Choices> choices;
    @JsonProperty("usage")
    private Usage usage;
    @JsonProperty("video_result")
    private List<VideoResult> videoResult;
    @JsonProperty("web_search")
    private List<WebSearch> webSearch;
    @JsonProperty("content_filter")
    private List<ContentFilter> contentFilter;
    @JsonProperty("error")
    private Error error;

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class Choices {
        @JsonProperty("index")
        private Integer index;
        @JsonProperty("finish_reason")
        private String finishReason;
        @JsonProperty("message")
        private Message message;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class Message {
        @JsonProperty("role")
        private String role;
        /**
         * 不适用于：GLM-4V
         */
        @JsonProperty("content")
        private String content;
        @JsonProperty("reasoning_content")
        private String reasoningContent;
        @JsonProperty("audio")
        private Audio audio;
    }

//    @Data
//    @NoArgsConstructor
//    @AllArgsConstructor
//    @JsonIgnoreProperties(ignoreUnknown = true)
//    @JsonInclude(JsonInclude.Include.NON_NULL)
//    public static class Content {
//        @JsonProperty("type")
//        private String type;
//        @JsonProperty("text")
//        private String text;
//    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class Audio {
        @JsonProperty("id")
        private String id;
        @JsonProperty("data")
        private String data;
        @JsonProperty("expires_at")
        private String expiresAt;
        @JsonProperty("tool_calls")
        private List<ToolCalls> toolCalls;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class ToolCalls {
        @JsonProperty("id")
        private String id;
        @JsonProperty("type")
        private String type;
        @JsonProperty("function")
        private Function function;
        @JsonProperty("mcp")
        private Mcp mcp;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class Function {
        @JsonProperty("name")
        private String name;
        @JsonProperty("arguments")
        private Object arguments;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class Mcp {
        @JsonProperty("id")
        private String id;
        @JsonProperty("type")
        private String type;
        @JsonProperty("server_label")
        private String serverLabel;
        @JsonProperty("error")
        private String error;
        @JsonProperty("tools")
        private List<Tools> tools;
        @JsonProperty("arguments")
        private String arguments;
        @JsonProperty("name")
        private String name;
        @JsonProperty("output")
        private Object output;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class Tools {
        @JsonProperty("name")
        private String name;
        @JsonProperty("description")
        private String description;
        @JsonProperty("annotations")
        private Object annotations;
        @JsonProperty("input_schema")
        private InputSchema inputSchema;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class InputSchema {
        @JsonProperty("type")
        private String type;
        @JsonProperty("properties")
        private Object properties;
        @JsonProperty("required")
        private List<String> required;
        @JsonProperty("additionalProperties")
        private Boolean additionalProperties;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class Usage {
        @JsonProperty("prompt_tokens")
        private Integer promptTokens;
        @JsonProperty("completion_tokens")
        private Integer completionTokens;
        @JsonProperty("prompt_tokens_details")
        private PromptTokensDetails promptTokensDetails;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class PromptTokensDetails {
        @JsonProperty("cached_tokens")
        private Integer cachedTokens;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class VideoResult {
        @JsonProperty("url")
        private String url;
        @JsonProperty("cover_image_url")
        private String coverImageUrl;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class WebSearch {
        @JsonProperty("icon")
        private String icon;
        @JsonProperty("title")
        private String title;
        @JsonProperty("link")
        private String link;
        @JsonProperty("media")
        private String media;
        @JsonProperty("publish_date")
        private String publishDate;
        @JsonProperty("content")
        private String content;
        @JsonProperty("refer")
        private String refer;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class ContentFilter {
        /**
         * 安全生效环节，包括 role = assistant 模型推理，role = user 用户输入，role = history 历史上下文
         */
        @JsonProperty("role")
        private String role;
        /**
         * 严重程度 level 0-3，level 0表示最严重，3表示轻微
         */
        @JsonProperty("level")
        private Integer level;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class Error {
        @JsonProperty("message")
        private String message;
        @JsonProperty("code")
        private String code;
    }
}